package com.shm.leetcode;

/**
 * 1185. 一周中的第几天
 * 给你一个日期，请你设计一个算法来判断它是对应一周中的哪一天。
 *
 * 输入为三个整数：day、month 和 year，分别表示日、月、年。
 *
 * 您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}。
 *
 *
 *
 * 示例 1：
 *
 * 输入：day = 31, month = 8, year = 2019
 * 输出："Saturday"
 * 示例 2：
 *
 * 输入：day = 18, month = 7, year = 1999
 * 输出："Sunday"
 * 示例 3：
 *
 * 输入：day = 15, month = 8, year = 1993
 * 输出："Sunday"
 *
 *
 * 提示：
 *
 * 给出的日期一定是在 1971 到 2100 年之间的有效日期。
 *
 * @author SHM
 */
public class DayOfTheWeek {
    /**
     * 题目保证日期是在 1971 到 2100 之间，我们可以计算给定日期距离 1970 的最后一天（星期四）间隔了多少天，从而得知给定日期是周几。
     *
     * 具体的，可以先通过循环处理计算年份在 [1971, year - 1][1971,year−1] 时间段，经过了多少天（注意平年为 365365，闰年为 366366）；然后再处理当前年 yearyear 的月份在 [1, month - 1][1,month−1] 时间段 ，经过了多少天（注意当天年是否为闰年，特殊处理 22 月份），最后计算当前月 monthmonth 经过了多少天，即再增加 dayday 天。
     *
     * 得到距离 1970 的最后一天（星期四）的天数后进行取模，即可映射回答案。
     * 时间复杂度：令当前时间 2100-12-xx，此时达到数据范围对应的计算量上界，设为 CC。整体复杂度为 O(C)O(C)
     * 空间复杂度：O(1)O(1)
     *
     * 作者：AC_OIer
     * 链接：https://leetcode-cn.com/problems/day-of-the-week/solution/gong-shui-san-xie-jian-dan-ri-qi-tong-ji-czt6/
     * @param day
     * @param month
     * @param year
     * @return
     */
    public String dayOfTheWeek(int day, int month, int year) {
        String[] week = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
        int[] nums = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int sumDay = 0;
        for (int i = 1971; i < year; i++) {
            if ((i%4==0&&i%100!=0)||i%400==0){
                sumDay+=366;
            }else{
                sumDay+=365;
            }
        }
        for (int i = 1; i < month; i++) {
            sumDay+=nums[i-1];
            if (i==2&&((year%4==0&&year%100!=0)||year%400==0)){
                sumDay+=1;
            }
        }
        sumDay+=day;
        return week[(sumDay+3)%7];
    }
}
